{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# TODO: Predict Reviews with BERT in the Notebook (AdHoc)\n",
    "\n",
    "# Note:  this no longer works properly as it's using the `transformers/fine-tuned` model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import boto3\n",
    "import sagemaker\n",
    "import pandas as pd\n",
    "\n",
    "sess   = sagemaker.Session()\n",
    "bucket = sess.default_bucket()\n",
    "role = sagemaker.get_execution_role()\n",
    "region = boto3.Session().region_name\n",
    "\n",
    "sm = boto3.Session().client(service_name='sagemaker', region_name=region)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Retrieve the Training Job Name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "%store -r training_job_name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "try:\n",
    "    training_job_name\n",
    "except NameError:\n",
    "    print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')\n",
    "    print('[ERROR] Please wait for the previous notebook to finish.')\n",
    "    print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Previous training_job_name: tensorflow-training-2021-01-03-05-49-48-016\n"
     ]
    }
   ],
   "source": [
    "print('Previous training_job_name: {}'.format(training_job_name))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Download the Trained Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "models_dir = './models'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "download: s3://sagemaker-us-east-1-835319576252/tensorflow-training-2021-01-03-05-49-48-016/output/model.tar.gz to models/model.tar.gz\n"
     ]
    }
   ],
   "source": [
    "# Download the model and output artifacts from AWS S3\n",
    "!aws s3 cp s3://$bucket/$training_job_name/output/model.tar.gz $models_dir/model.tar.gz"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tarfile\n",
    "import pickle as pkl\n",
    "\n",
    "#!ls -al ./models\n",
    "\n",
    "tar = tarfile.open('{}/model.tar.gz'.format(models_dir))\n",
    "tar.extractall(path=models_dir)\n",
    "tar.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "total 835436\r\n",
      "drwxrwxr-x  8 ec2-user ec2-user      4096 Jan  3 06:47 .\r\n",
      "drwxrwxr-x 17 ec2-user ec2-user      4096 Jan  3 06:47 ..\r\n",
      "drwxr-xr-x  2 ec2-user ec2-user      4096 Jan  3 06:07 code\r\n",
      "drwxr-xr-x  2 ec2-user ec2-user      4096 Jan  3 06:09 metrics\r\n",
      "-rw-rw-r--  1 ec2-user ec2-user 855452891 Jan  3 06:11 model.tar.gz\r\n",
      "drwxr-xr-x  4 ec2-user ec2-user      4096 Jan  3 05:58 tensorboard\r\n",
      "drwxr-xr-x  3 ec2-user ec2-user      4096 Jan  3 05:56 tensorflow\r\n",
      "drwxr-xr-x  2 ec2-user ec2-user      4096 Jan  3 06:07 test_data\r\n",
      "drwxr-xr-x  3 ec2-user ec2-user      4096 Jan  3 05:56 transformers\r\n"
     ]
    }
   ],
   "source": [
    "!ls -al $models_dir"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Load the Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "total 259360\r\n",
      "drwxr-xr-x 2 ec2-user ec2-user      4096 Jan  3 05:58 .\r\n",
      "drwxr-xr-x 3 ec2-user ec2-user      4096 Jan  3 05:56 ..\r\n",
      "-rw-r--r-- 1 ec2-user ec2-user       648 Jan  3 05:58 config.json\r\n",
      "-rw-r--r-- 1 ec2-user ec2-user 265569984 Jan  3 05:58 tf_model.h5\r\n"
     ]
    }
   ],
   "source": [
    "transformer_model_dir = '{}/transformers/fine-tuned/'.format(models_dir)\n",
    "\n",
    "!ls -al $transformer_model_dir"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\r\n",
      "  \"_name_or_path\": \"distilbert-base-uncased\",\r\n",
      "  \"activation\": \"gelu\",\r\n",
      "  \"architectures\": [\r\n",
      "    \"DistilBertForMaskedLM\"\r\n",
      "  ],\r\n",
      "  \"attention_dropout\": 0.1,\r\n",
      "  \"dim\": 768,\r\n",
      "  \"dropout\": 0.1,\r\n",
      "  \"hidden_dim\": 3072,\r\n",
      "  \"id2label\": {\r\n",
      "    \"0\": 1,\r\n",
      "    \"1\": 2,\r\n",
      "    \"2\": 3,\r\n",
      "    \"3\": 4,\r\n",
      "    \"4\": 5\r\n",
      "  },\r\n",
      "  \"initializer_range\": 0.02,\r\n",
      "  \"label2id\": {\r\n",
      "    \"1\": 0,\r\n",
      "    \"2\": 1,\r\n",
      "    \"3\": 2,\r\n",
      "    \"4\": 3,\r\n",
      "    \"5\": 4\r\n",
      "  },\r\n",
      "  \"max_position_embeddings\": 512,\r\n",
      "  \"model_type\": \"distilbert\",\r\n",
      "  \"n_heads\": 12,\r\n",
      "  \"n_layers\": 6,\r\n",
      "  \"pad_token_id\": 0,\r\n",
      "  \"qa_dropout\": 0.1,\r\n",
      "  \"seq_classif_dropout\": 0.2,\r\n",
      "  \"sinusoidal_pos_embds\": false,\r\n",
      "  \"tie_weights_\": true,\r\n",
      "  \"vocab_size\": 30522\r\n",
      "}\r\n"
     ]
    }
   ],
   "source": [
    "cat $transformer_model_dir/config.json"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "All model checkpoint layers were used when initializing TFDistilBertForSequenceClassification.\n",
      "\n",
      "Some layers of TFDistilBertForSequenceClassification were not initialized from the model checkpoint at ./models/transformers/fine-tuned/ and are newly initialized: ['pre_classifier', 'classifier', 'dropout_19']\n",
      "You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "from transformers import TFDistilBertForSequenceClassification\n",
    "\n",
    "loaded_model = TFDistilBertForSequenceClassification.from_pretrained(transformer_model_dir,\n",
    "                                                                     id2label={\n",
    "                                                                       0: 1,\n",
    "                                                                       1: 2,\n",
    "                                                                       2: 3,\n",
    "                                                                       3: 4,\n",
    "                                                                       4: 5\n",
    "                                                                     },\n",
    "                                                                     label2id={\n",
    "                                                                       1: 0,\n",
    "                                                                       2: 1,\n",
    "                                                                       3: 2,\n",
    "                                                                       4: 3,\n",
    "                                                                       5: 4\n",
    "                                                                     })"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "inference_device -1\n"
     ]
    }
   ],
   "source": [
    "from transformers import DistilBertTokenizer\n",
    "\n",
    "tokenizer = DistilBertTokenizer.from_pretrained('distilbert-base-uncased')\n",
    "\n",
    "inference_device = -1 # CPU: -1, GPU: 0\n",
    "print('inference_device {}'.format(inference_device))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "from transformers import TextClassificationPipeline\n",
    "\n",
    "inference_pipeline = TextClassificationPipeline(model=loaded_model, \n",
    "                                                tokenizer=tokenizer,\n",
    "                                                framework='tf',\n",
    "                                                device=inference_device) # -1 is CPU, >= 0 is GPU"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# THESE PREDICTIONS WILL NOT BE ACCURATE  \n",
    "\n",
    "Here are the reasons:\n",
    "* we are not using the full dataset\n",
    "* we are only training for 50 steps\n",
    "* we are using a small training cluster\n",
    "\n",
    "_This same BERT model achieves close to 97% accuracy when training longer, using a larger training cluster, and using more data._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I loved it! [{'label': 1, 'score': 0.21490779519081116}]\n"
     ]
    }
   ],
   "source": [
    "review = \"\"\"I loved it!\"\"\"\n",
    "print(review, inference_pipeline(review))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Not that good. [{'label': 1, 'score': 0.21912693977355957}]\n"
     ]
    }
   ],
   "source": [
    "review = \"\"\"Not that good.\"\"\"\n",
    "print(review, inference_pipeline(review))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Test Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(100, 2)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import csv\n",
    "\n",
    "df_test_reviews = pd.read_csv('./data/amazon_reviews_us_Digital_Software_v1_00.tsv.gz', \n",
    "                                delimiter='\\t', \n",
    "                                quoting=csv.QUOTE_NONE,\n",
    "                                compression='gzip')[['review_body', 'star_rating']]\n",
    "\n",
    "df_test_reviews = df_test_reviews.sample(n=100)\n",
    "\n",
    "df_test_reviews.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Actual Star Rating"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>review_body</th>\n",
       "      <th>star_rating</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>6347</th>\n",
       "      <td>I have used Quicken for several years, but thi...</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>61100</th>\n",
       "      <td>I have been using avast! for 2 years, and I ha...</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>94262</th>\n",
       "      <td>After installing the software, it was very eas...</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>44047</th>\n",
       "      <td>Nice</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>81284</th>\n",
       "      <td>I have used Quicken for years. Having the mobi...</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                             review_body  star_rating\n",
       "6347   I have used Quicken for several years, but thi...            3\n",
       "61100  I have been using avast! for 2 years, and I ha...            5\n",
       "94262  After installing the software, it was very eas...            5\n",
       "44047                                               Nice            5\n",
       "81284  I have used Quicken for years. Having the mobi...            5"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_test_reviews.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6347      3\n",
       "61100     5\n",
       "94262     5\n",
       "44047     5\n",
       "81284     5\n",
       "         ..\n",
       "69686     1\n",
       "100189    5\n",
       "43601     5\n",
       "80296     1\n",
       "100718    4\n",
       "Name: star_rating, Length: 100, dtype: int64"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_actual = df_test_reviews['star_rating']\n",
    "\n",
    "y_actual"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Predicted Star Rating"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6347      1\n",
       "61100     1\n",
       "94262     1\n",
       "44047     1\n",
       "81284     1\n",
       "         ..\n",
       "69686     4\n",
       "100189    1\n",
       "43601     1\n",
       "80296     4\n",
       "100718    4\n",
       "Name: review_body, Length: 100, dtype: int64"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "\n",
    "def predict(review_body):\n",
    "    prediction_map = inference_pipeline(review_body[0:512])\n",
    "    return prediction_map[0]['label']\n",
    "    \n",
    "y_test = df_test_reviews['review_body'].map(predict)\n",
    "\n",
    "y_test"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Classification Report:  Compare Actual to Predicted"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           1       0.30      0.11      0.16        56\n",
      "           2       0.07      1.00      0.13         1\n",
      "           3       0.00      0.00      0.00         0\n",
      "           4       0.24      0.12      0.16        43\n",
      "           5       0.00      0.00      0.00         0\n",
      "\n",
      "    accuracy                           0.12       100\n",
      "   macro avg       0.12      0.24      0.09       100\n",
      "weighted avg       0.27      0.12      0.16       100\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import classification_report\n",
    "\n",
    "print(classification_report(y_true=y_test, y_pred=y_actual))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Accuracy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy:  0.12\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "print('Test accuracy: ', accuracy_score(y_true=y_test, y_pred=y_actual))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Confusion Matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import pandas as pd\n",
    "\n",
    "def plot_conf_mat(cm, classes, title, cmap = plt.cm.Greens):\n",
    "    print(cm)\n",
    "    plt.imshow(cm, interpolation='nearest', cmap=cmap)\n",
    "    plt.title(title)\n",
    "    plt.colorbar()\n",
    "    tick_marks = np.arange(len(classes))\n",
    "    plt.xticks(tick_marks, classes, rotation=45)\n",
    "    plt.yticks(tick_marks, classes)\n",
    "\n",
    "    fmt = 'd'\n",
    "    thresh = cm.max() / 2.\n",
    "    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n",
    "        plt.text(j, i, format(cm[i, j], fmt),\n",
    "        horizontalalignment=\"center\",\n",
    "        color=\"black\" if cm[i, j] > thresh else \"black\")\n",
    "\n",
    "        plt.tight_layout()\n",
    "        plt.ylabel('True label')\n",
    "        plt.xlabel('Predicted label')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 6  7  3 16 24]\n",
      " [ 0  1  0  0  0]\n",
      " [ 0  0  0  0  0]\n",
      " [14  6  2  5 16]\n",
      " [ 0  0  0  0  0]]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 432x288 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x360 with 2 Axes>"
      ]
     },
     "metadata": {
      "image/png": {
       "height": 351,
       "width": 400
      },
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import itertools\n",
    "import numpy as np\n",
    "from sklearn.metrics import confusion_matrix\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "%config InlineBackend.figure_format='retina'\n",
    "\n",
    "cm = confusion_matrix(y_true=y_test, y_pred=y_actual)\n",
    "\n",
    "plt.figure()\n",
    "fig, ax = plt.subplots(figsize=(10,5))\n",
    "plot_conf_mat(cm, \n",
    "              classes=['1', '2', '3', '4', '5'], \n",
    "              title='Confusion Matrix')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "Jupyter.notebook.save_checkpoint();\n",
       "Jupyter.notebook.session.delete();\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%javascript\n",
    "Jupyter.notebook.save_checkpoint();\n",
    "Jupyter.notebook.session.delete();"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "conda_python3",
   "language": "python",
   "name": "conda_python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
